package com.csit.dao.impl;

import java.util.Date;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;

import com.csit.bean.Pager;
import com.csit.dao.SaleDetailDao;
import com.csit.entity.Sale;
import com.csit.entity.SaleDetail;
import com.csit.util.StringUtil;

@Repository
public class SaleDetailDaoImpl extends BaseDaoImpl<SaleDetail, Integer> implements SaleDetailDao {

	public Pager querySaleDetail(Pager pager, Sale sale, Date beginDate,Date endDate) {
		
		Criteria criteria = getSession().createCriteria(SaleDetail.class);
		criteria.createAlias("sale", "sale", CriteriaSpecification.LEFT_JOIN);
		criteria.createAlias("sale.customer", "customer", CriteriaSpecification.LEFT_JOIN);
		criteria.add(Restrictions.eq("sale.shop", sale.getShop()));
		if(StringUtil.isNotNull(sale.getSaleCode())){
			criteria.add(Restrictions.like("sale.saleCode", sale.getSaleCode(), MatchMode.ANYWHERE));
		}
		if(beginDate!=null){
			criteria.add(Restrictions.ge("sale.saleDate",beginDate));
		}
		if(endDate!=null){
			criteria.add(Restrictions.le("sale.saleDate", endDate));
		}
		
		Long totalCount = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();

		criteria.setProjection(null);
		criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		criteria.setFirstResult(pager.getBeginCount());
		criteria.setMaxResults(pager.getPageSize());
		criteria.addOrder(Order.desc("sale.saleCode")).addOrder(Order.asc("position"));
		pager.setTotalCount(totalCount);
		pager.setList(criteria.list());
		return pager;
	}

	public Pager querySaleDetail(Pager pager, Sale sale, SaleDetail saleDetail,Date beginDate,Date endDate) {
		Criteria criteria = getSession().createCriteria(SaleDetail.class);
		criteria.createAlias("sale", "sale", CriteriaSpecification.LEFT_JOIN);
		if(sale.getShop()!=null){
			criteria.add(Restrictions.eq("sale.shop", sale.getShop()));
		}
		if(saleDetail.getProduct()!=null){
			criteria.add(Restrictions.eq("product", saleDetail.getProduct()));
		}
		if(beginDate!=null){
			criteria.add(Restrictions.ge("sale.saleDate",beginDate));
		}
		if(endDate!=null){
			criteria.add(Restrictions.le("sale.saleDate", endDate));
		}
		
		Long totalCount = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();

		criteria.setProjection(null);
		criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		criteria.setFirstResult(pager.getBeginCount());
		criteria.setMaxResults(pager.getPageSize());
		criteria.addOrder(Order.desc("sale.saleCode")).addOrder(Order.asc("position"));
		pager.setTotalCount(totalCount);
		pager.setList(criteria.list());
		return pager;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Double> queryTotal(Sale sale, SaleDetail saleDetail,Date beginDate, Date endDate) {
		StringBuilder hql = new StringBuilder(
				"select sum(isnull(a.quantity,0)) as totalQty,sum(isnull(a.amount,0)) as totalAmount from SaleDetail a left join a.sale b where 1=1");
		if (sale.getShop() != null) {
			hql.append(" and b.shop=:shop");
		}
		if (saleDetail.getProduct() != null) {
			hql.append(" and a.product=:product");
		}
		if (beginDate!=null) {
			hql.append(" and b.saleDate>=:beginDate");
		}
		if (endDate!=null) {
			hql.append(" and b.saleDate<=:endDate");
		}
		Query query = getSession().createQuery(hql.toString());

		if (sale.getShop() != null) {
			query.setEntity("shop", sale.getShop());
		}
		if (saleDetail.getProduct() != null) {
			query.setEntity("product", saleDetail.getProduct());
		}
		if (beginDate!=null) {
			query.setDate("beginDate", beginDate);
		}
		if (endDate!=null) {
			query.setDate("endDate", endDate);
		}
		query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

		return (Map<String, Double>) query.uniqueResult();
	}

}
